import os
import logging
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client
from qcloud_cos.cos_exception import CosClientError, CosServiceError
import dotenv
from pathlib import Path

# 加载.env文件
env_path = Path(__file__).parent / '.env'
if env_path.exists():
    dotenv.load_dotenv(dotenv_path=env_path)

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 腾讯云COS配置
class COSConfig:
    # 从环境变量中读取配置，如果环境变量不存在则使用默认值
    SECRET_ID = os.environ.get("COS_SECRET_ID", "AKID6891lppmn5PsVPI7Z6xpW8c0M1kYKWjq")
    SECRET_KEY = os.environ.get("COS_SECRET_KEY", "TsG18Hf5eVNX1TmL9vxsp8WtmcZWo6Tp")
    REGION = os.environ.get("COS_REGION", "ap-nanjing")
    BUCKET = os.environ.get("COS_BUCKET", "wushuang233-1316633667")
    DOMAIN = os.environ.get("COS_DOMAIN", "https://wushuang233-1316633667.cos.ap-nanjing.myqcloud.com")
    APP_ID = os.environ.get("COS_APP_ID", "1316633667")

# 初始化COS客户端
def get_cos_client():
    """获取COS客户端"""
    # 检查是否配置了访问凭证
    if not COSConfig.SECRET_ID or not COSConfig.SECRET_KEY:
        logger.warning("未配置腾讯云COS访问凭证，请设置COS_SECRET_ID和COS_SECRET_KEY环境变量")
        return None

    config = CosConfig(
        Region=COSConfig.REGION,
        SecretId=COSConfig.SECRET_ID,
        SecretKey=COSConfig.SECRET_KEY
    )
    return CosS3Client(config)

# 上传文件到COS
def upload_file(local_file_path, cos_file_path=None):
    """
    上传文件到腾讯云COS
    :param local_file_path: 本地文件路径
    :param cos_file_path: COS上的文件路径，如果为None则使用文件名
    :return: 上传成功返回文件URL，失败返回None
    """
    if not os.path.exists(local_file_path):
        logger.error(f"上传失败：本地文件不存在 - {local_file_path}")
        return None
    
    # 获取COS客户端
    client = get_cos_client()
    if client is None:
        logger.error("无法获取COS客户端，请检查配置")
        # 如果无法获取客户端，返回本地文件路径
        return os.path.basename(local_file_path)
    
    # 如果没有指定COS路径，则使用文件名
    if cos_file_path is None:
        cos_file_path = os.path.basename(local_file_path)
    
    try:
        # 执行上传
        response = client.upload_file(
            Bucket=COSConfig.BUCKET,
            LocalFilePath=local_file_path,
            Key=cos_file_path,
            EnableMD5=True
        )
        
        # 构建URL
        file_url = f"{COSConfig.DOMAIN}/{cos_file_path}"
        logger.info(f"文件上传成功: {file_url}")
        return file_url
    
    except CosClientError as e:
        logger.error(f"客户端错误: {e}")
        # 上传失败时，返回本地文件路径作为备选
        return os.path.basename(local_file_path)
    except CosServiceError as e:
        logger.error(f"服务端错误: {e}")
        return os.path.basename(local_file_path)
    except Exception as e:
        logger.error(f"上传过程中发生错误: {e}")
        return os.path.basename(local_file_path)

# 从COS下载文件
def download_file(cos_file_path, local_file_path):
    """
    从腾讯云COS下载文件
    :param cos_file_path: COS上的文件路径
    :param local_file_path: 下载到本地的路径
    :return: 下载成功返回True，失败返回False
    """
    client = get_cos_client()
    
    try:
        # 确保本地目录存在
        os.makedirs(os.path.dirname(os.path.abspath(local_file_path)), exist_ok=True)
        
        # 执行下载
        response = client.download_file(
            Bucket=COSConfig.BUCKET,
            Key=cos_file_path,
            DestFilePath=local_file_path
        )
        
        logger.info(f"文件下载成功: {local_file_path}")
        return True
    
    except CosClientError as e:
        logger.error(f"客户端错误: {e}")
        return False
    except CosServiceError as e:
        logger.error(f"服务端错误: {e}")
        return False
    except Exception as e:
        logger.error(f"下载过程中发生错误: {e}")
        return False

# 删除COS上的文件
def delete_file(cos_file_path):
    """
    删除腾讯云COS上的文件
    :param cos_file_path: COS上的文件路径
    :return: 删除成功返回True，失败返回False
    """
    client = get_cos_client()
    
    try:
        # 执行删除
        response = client.delete_object(
            Bucket=COSConfig.BUCKET,
            Key=cos_file_path
        )
        
        logger.info(f"文件删除成功: {cos_file_path}")
        return True
    
    except CosClientError as e:
        logger.error(f"客户端错误: {e}")
        return False
    except CosServiceError as e:
        logger.error(f"服务端错误: {e}")
        return False
    except Exception as e:
        logger.error(f"删除过程中发生错误: {e}")
        return False

# 检查文件是否存在
def file_exists(cos_file_path):
    """
    检查腾讯云COS上是否存在指定文件
    :param cos_file_path: COS上的文件路径
    :return: 存在返回True，不存在返回False
    """
    client = get_cos_client()
    
    try:
        # 执行查询
        response = client.object_exists(
            Bucket=COSConfig.BUCKET,
            Key=cos_file_path
        )
        
        return response
    
    except CosClientError as e:
        logger.error(f"客户端错误: {e}")
        return False
    except CosServiceError as e:
        logger.error(f"服务端错误: {e}")
        return False
    except Exception as e:
        logger.error(f"查询过程中发生错误: {e}")
        return False

# 生成预签名URL
def generate_presigned_url(cos_file_path, expire_seconds=3600):
    """
    生成预签名URL，用于临时访问私有文件
    :param cos_file_path: COS上的文件路径
    :param expire_seconds: 链接有效期，单位秒
    :return: 预签名URL
    """
    client = get_cos_client()
    
    try:
        # 生成预签名URL
        url = client.get_presigned_url(
            Method='GET',
            Bucket=COSConfig.BUCKET,
            Key=cos_file_path,
            Expired=expire_seconds
        )
        
        return url
    
    except Exception as e:
        logger.error(f"生成预签名URL过程中发生错误: {e}")
        return None 